package com.shop.cereshop.app.service.recommend.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.shop.cereshop.app.dao.buyer.BuyerUserBlacklistMapper;
import com.shop.cereshop.app.dao.collect.CereBuyerCollectDAO;
import com.shop.cereshop.app.dao.recommend.*;
import com.shop.cereshop.app.dao.tim.moderation.VideoModerationTaskMapper;
import com.shop.cereshop.app.page.buyer.UserDetailVO;
import com.shop.cereshop.app.page.collect.CollectShop;
import com.shop.cereshop.app.page.recommend.*;
import com.shop.cereshop.app.param.recommend.*;
import com.shop.cereshop.app.redis.config.SysThreadPool;
import com.shop.cereshop.app.service.buyer.CereBuyerUserService;
import com.shop.cereshop.app.service.collect.CereBuyerCollectService;
import com.shop.cereshop.app.service.nearbyUser.NearbyUserService;
import com.shop.cereshop.app.service.recommend.*;
import com.shop.cereshop.app.utils.RedisUtil;
import com.shop.cereshop.commons.cache.constants.CacheKeyConstants;
import com.shop.cereshop.commons.constant.CoReturnFormat;
import com.shop.cereshop.commons.domain.buyer.CereBuyerUser;
import com.shop.cereshop.commons.domain.common.Page;
import com.shop.cereshop.commons.domain.im.tx.req.follow.FollowCheckReq;
import com.shop.cereshop.commons.domain.im.tx.req.follow.FollowGetReq;
import com.shop.cereshop.commons.domain.im.tx.resp.follow.FollowGetResp;
import com.shop.cereshop.commons.domain.im.tx.resp.follow.FollowUserResp;
import com.shop.cereshop.commons.domain.recommend.CereRecommendFootprint;
import com.shop.cereshop.commons.domain.recommend.CereRecommendTrends;
import com.shop.cereshop.commons.domain.recommend.RecommendAtUser;
import com.shop.cereshop.commons.enums.RedisEnum;
import com.shop.cereshop.commons.enums.recommend.RecommendLikeTypeEnum;
import com.shop.cereshop.commons.enums.recommend.RecommendOptionEnum;
import com.shop.cereshop.commons.enums.recommend.RecommendPublishEnum;
import com.shop.cereshop.commons.exception.CoBusinessException;
import com.shop.cereshop.commons.service.im.ImUserService;
import com.shop.cereshop.commons.tencent.moderation.domain.entity.VideoModerationTask;
import com.shop.cereshop.commons.tencent.moderation.enums.VideoTaskTypeEnum;
import com.shop.cereshop.commons.utils.EmptyUtils;
import com.shop.cereshop.commons.utils.GeoHashUtil;
import com.shop.cereshop.commons.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;


@Service
@Slf4j
public class CereRecommendTrendsServiceImpl implements CereRecommendTrendsService {

    @Value("${time.format}")
    private String timeFormat;
    @Resource
    private NearbyUserService nearbyService;
    @Resource
    private CereRecommendTrendsDAO cereRecommendTrendsDAO;
    @Resource
    private CereRecommendRelationDAO cereRecommendRelationDAO;
    @Resource
    private CereBuyerCollectDAO cereBuyerCollectDAO;
    @Resource
    private CereRecommendLikesDAO cereRecommendLikesDAO;
    @Resource
    private CereRecommendTypeRelationDAO cereRecommendTypeRelationDAO;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private RedissonClient redissonClient;
    @Resource
    private CereRecommendDraftService cereRecommendDraftService;
    @Resource
    private CereRecommendCommentService cereRecommendCommentService;
    @Resource
    private CereRecommendLikesService cereRecommendLikesService;
    @Resource(name = "ImUserService")
    private ImUserService imUserService;
    @Resource
    private CereBuyerCollectService cereBuyerCollectService;
    @Resource
    private RecommendAtUserDAO recommendAtUserDAO;
    @Resource
    private CereBuyerUserService cereBuyerUserService;
    @Resource
    private CereRecommendFootprintService cereRecommendFootprintService;
    @Resource
    private CereRecommendFootprintDAO cereRecommendFootprintDAO;
    @Resource
    private VideoModerationTaskMapper videoModerationTaskMapper;
    @Resource
    private BuyerUserBlacklistMapper buyerUserBlacklistMapper;

    @Resource
    private SysThreadPool sysThreadPool;


    @Override
    public Page<CereRecommendTrendPageVO> trendPage(RecommendTrendPageParam param) {
        // 关注店铺
        if (param.getRecommendType() != null && param.getRecommendType() == 0) {
            List<CollectShop> collectShops = cereBuyerCollectDAO.getAllShop(param.getUserId(), null);
            if (CollectionUtil.isNotEmpty(collectShops)) {
                param.setCollectShopIds(collectShops.stream().map(CollectShop::getShopId).collect(Collectors.toList()));
            } else {
                param.setShopId(0L);
            }
        }
        PageHelper.startPage(param.getPage(), param.getPageSize());
        PageInfo<CereRecommendTrendPageVO> pageInfo = new PageInfo<>(cereRecommendTrendsDAO.trendPage(param));
        Page<CereRecommendTrendPageVO> page = new Page(pageInfo.getList(), pageInfo.getTotal());
        return page;
    }

    @Override
    public CereRecommendTrendDetailVO getTrend(RecommendLikesParam param) throws Exception {
        CereRecommendTrendDetailVO vo = cereRecommendTrendsDAO.getTrendById(param.getRecommendId());
        if (ObjectUtil.isNotEmpty(vo.getPublishTime())) {
            int day = TimeUtils.differentDaysByMillisecond(vo.getPublishTime());
            vo.setDay(day > 0 ? day + "天前" : "今天");
        }
        BusinessShopInfo shopInfo = cereRecommendTrendsDAO.getPlatformShop(vo.getShopId(), param.getUserId());
        vo.setProducts(cereRecommendRelationDAO.getRecommendProducts(param.getRecommendId()));
        vo.setLikeStatus(ObjectUtil.isNotNull(cereRecommendLikesDAO.getLikes(param)) ? 1 : 0);
        vo.setIsCollect(shopInfo.getIsCollect());
        vo.setAvatar(shopInfo.getAvatar());
        vo.setName(shopInfo.getName());
        return vo;
    }

    @Override
    public void share(Long recommendId) {
        cereRecommendTrendsDAO.addShareCount(recommendId);
    }

    @Override
    public BusinessShopInfo getShopInfo(Long shopId, Long userId) {
        return cereRecommendTrendsDAO.getPlatformShop(shopId, userId);
    }

    /**
     * 获取动态分页
     *
     * @param param
     * @param user
     * @return
     */
    @Override
    public Page<RecommendPageVO> getRecommendPage(RecommendPageDTO param, CereBuyerUser user) throws CoBusinessException {
        if (ObjectUtil.isNotNull(param.getRecommendTypeId())) {
            //话题详情下的动态列表
            param.setFilter(2);
        } else if (StrUtil.isNotBlank(param.getKeyword())) {
            //搜索的动态列表
            param.setFilter(4);
        } else if (ObjectUtil.isNotNull(param.getBuyerUserId()) && ObjectUtil.isNull(param.getOption())) {
            //个人中心动态列表
            param.setFilter(3);
        } else if (ObjectUtil.isNotNull(param.getOption()) && ObjectUtil.isNotNull(param.getBuyerUserId()) && param.getOption().equals(RecommendOptionEnum.LIKE.getCode())) {
            //赞过的动态列表
            param.setFilter(5);
        } else if (ObjectUtil.isNotNull(param.getOption()) && ObjectUtil.isNotNull(param.getBuyerUserId()) && param.getOption().equals(RecommendOptionEnum.COLLECT.getCode())) {
            //收藏的动态列表
            param.setFilter(6);
        } else if (ObjectUtil.isNotNull(param.getOption()) && param.getOption().equals(RecommendOptionEnum.CONCERN.getCode())) {
            //关注列表
            param.setFilter(7);
        } else {
            //首页动态列表
            param.setFilter(1);
        }

        // 被当前用户标记为"拉黑"和"我不看他"的被拉黑用户列表
        List<Long> blockedUserIds = buyerUserBlacklistMapper.getBlockedHisPostsUserIds(user.getBuyerUserId());
        param.setBlockedUserIds(blockedUserIds);

        switch (param.getFilter()) {
            //1-首页动态列表
            case 1:
                return getRecommendWithIndex(param, user);
            //2-话题详情页的动态列表
            case 2:
                return getRecommendWithType(param, user);
            //3-个人中心的动态列表
            case 3:
                return getRecommendWithUser(param, user);
            //4-搜索的动态列表
            case 4:
                return getRecommendWithSearch(param, user);
            //5-赞过的动态列表
            case 5:
                RecommendLikeDTO likeDTO = new RecommendLikeDTO();
                likeDTO.setFilter(2);
                likeDTO.setTargetId(param.getBuyerUserId());
                likeDTO.setLikeType(1);
                likeDTO.setPageSize(param.getPageSize());
                likeDTO.setPage(param.getPage());
                if (ObjectUtil.isNotNull(param.getRecommendId())) {
                    likeDTO.setRecommendId(param.getRecommendId());
                }
                likeDTO.setBlockedUserIds(blockedUserIds);
                return getCollectAndLikePage(likeDTO, user);
            //6-收藏的动态列表
            case 6:
                RecommendLikeDTO collectDTO = new RecommendLikeDTO();
                collectDTO.setFilter(1);
                collectDTO.setTargetId(param.getBuyerUserId());
                collectDTO.setLikeType(1);
                collectDTO.setPageSize(param.getPageSize());
                collectDTO.setPage(param.getPage());
                if (ObjectUtil.isNotNull(param.getRecommendId())) {
                    collectDTO.setRecommendId(param.getRecommendId());
                }
                collectDTO.setBlockedUserIds(blockedUserIds);
                return getCollectAndLikePage(collectDTO, user);
            //7-关注列表
            case 7:
                return getMyConcernRecommends(param, user);
            default:
                throw new CoBusinessException(CoReturnFormat.PARAM_INVALID, "不支持的筛选条件");
        }
    }

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {CoBusinessException.class, Exception.class})
    public RecommendPageVO getRecommendDetail(Long recommendId, CereBuyerUser user) {
        RecommendPageVO recommendDetail = cereRecommendTrendsDAO.getRecommendDetail(recommendId, user.getBuyerUserId());
        RecommendFootPrintDTO recommendFootPrintDTO = new RecommendFootPrintDTO();
        recommendFootPrintDTO.setRecommendPageVO(recommendDetail);
        //todo 增加用户动态历史访问记录
        addRecommendFootPrint(recommendFootPrintDTO, user.getBuyerUserId());
        recommendDetail.init();
        fillUserInfo(Collections.singletonList(recommendDetail), user, false);

        return recommendDetail;
    }

    @Async
    public void addRecommendFootPrint(RecommendFootPrintDTO param, Long userId) {
        if (param == null || userId == null) {
            log.warn("添加足迹参数为空: param={}, userId={}", param, userId);
            return;
        }
        //查询是否存在足迹
        CereRecommendFootprint one = cereRecommendFootprintService.lambdaQuery()
                .eq(CereRecommendFootprint::getBuyerUserId, userId)
                .eq(CereRecommendFootprint::getTargetId, param.getRecommendPageVO().getRecommendId())
                .eq(CereRecommendFootprint::getFootprintType, param.getRecommendPageVO().getFileType())
                .one();
        if (one != null) {
            //存在则更新
            cereRecommendFootprintService.lambdaUpdate()
                    .set(CereRecommendFootprint::getUpdateTime, new Date())
                    .eq(CereRecommendFootprint::getRecommendFootprintId, one.getRecommendFootprintId())
                    .update();
            return;
        }
        //不存在则新增
        CereRecommendFootprint footprint = new CereRecommendFootprint();
        footprint.setBuyerUserId(userId);
        footprint.setTargetId(param.getRecommendPageVO().getRecommendId());
        footprint.setFootprintType(param.getRecommendPageVO().getFileType());
        cereRecommendFootprintService.save(footprint);
    }

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {CoBusinessException.class, Exception.class})
    public int saveRecommend(RecommendSaveDTO param, CereBuyerUser user,Integer publishStatus) throws CoBusinessException {
        //获取当前时间
        String now = TimeUtils.yyMMddHHmmss();
//        判断前用户是否可以发布动态
        if (user.getIfAllowTrends()==0){
            return 0;
        }
        //如果动态id不为null，则修改动态
        if (param.getRecommendId() != null) {
            CereRecommendTrends trends = BeanUtil.copyProperties(param, CereRecommendTrends.class);
            trends.setBuyerUserId(user.getBuyerUserId());
            trends.setUpdateTime(now);
            return cereRecommendTrendsDAO.updateById(trends);
        }
        //如果草稿箱id不为null，则删除草稿箱
        if (param.getDraftId() != null) {
            cereRecommendDraftService.removeById(param.getDraftId());
        }
        //初始化并设置属性
        CereRecommendTrends trends = new CereRecommendTrends();
        BeanUtil.copyProperties(param, trends);
        trends.setBuyerUserId(user.getBuyerUserId());
//        trends.setPublishStatus(RecommendPublishEnum.AUDIT_SUCCESS.getCode());
        //图文类型则取第一张图片作为封面
        if (StrUtil.isBlank(trends.getCover()) && trends.getFileType() == 1) {
            trends.setCover(trends.getFileUrl().split(",")[0]);
        }
        trends.setPublishStatus(publishStatus);
        if (publishStatus == 1){
            trends.setReviewContent(RecommendPublishEnum.AUDIT_SUCCESS.getMsg());
        } else if (publishStatus==2) {
            trends.setReviewContent(RecommendPublishEnum.UNAUDITED.getMsg());

        }
        trends.setPublishTime(now);
        trends.setCreateTime(now);
        trends.setUpdateTime(now);
        if (StrUtil.isNotBlank(trends.getLocation())) {
            String[] locations = trends.getLocation().split(",");
            // location格式为"lng,lat"，GeoHashUtil.encode需要(latitude, longitude)
            trends.setLocationGeohash(GeoHashUtil.encode(Double.parseDouble(locations[1]), Double.parseDouble(locations[0]), 5));
        }
        //动态表添加数据
        int result = cereRecommendTrendsDAO.insert(trends);

        // 保存视频审核任务记录
        VideoModerationTask videoModerationTask = new VideoModerationTask();
        videoModerationTask.setTaskId(param.getTaskId());
        videoModerationTask.setType(VideoTaskTypeEnum.POSTS_VIDEO.getCode());
        videoModerationTask.setDataId(String.valueOf(trends.getRecommendId()));
        videoModerationTask.setStatus(param.getTaskStatus());
        videoModerationTask.setCreateTime(LocalDateTime.now());
        videoModerationTaskMapper.insertSelective(videoModerationTask);

        //动态话题关联表添加数据
        if (CollectionUtil.isNotEmpty(param.getRecommendTypeIdList())) {
            cereRecommendTypeRelationDAO.insertByIds(trends.getRecommendId(), param.getRecommendTypeIdList());
        }

        List<RecommendAtUser> recommendAtUserList = new ArrayList<>();
        //保存@的消息
        if (param.getAtUser() != null) {
            param.getAtUser().forEach(dto -> {
                RecommendAtUser recommendAtUser = new RecommendAtUser();
                recommendAtUser.setAtUserId(dto.getUserId());
                recommendAtUser.setAtUsername(dto.getName());
                recommendAtUser.setAtTargetId(trends.getRecommendId());
                recommendAtUser.setBuyerUserId(user.getBuyerUserId());
                recommendAtUser.setAtType(RecommendLikeTypeEnum.RECOMMEND.getCode());
                recommendAtUserList.add(recommendAtUser);
            });
        }
        //批量插入@信息操作
        if (CollectionUtil.isNotEmpty(recommendAtUserList)) {
            recommendAtUserDAO.insertBatch(recommendAtUserList);
        }

        //推送好友消息
//        PushInfo pushInfo = new PushInfo();
//        pushInfo.setFrom_Account(String.valueOf(user.getBuyerUserId()));
//        pushInfo.setTo_Account(Arrays.stream(
//                        param.getAtUserIds()
//                                .toArray())
//                .map(Object::toString)
//                .toArray(String[]::new));
//        pushInfo.setMsgRandom(System.currentTimeMillis() / 100000);
//        PushInfo.OfflinePushInfo offlinePushInfo = new PushInfo.OfflinePushInfo();
//        offlinePushInfo.setPushFlag(1);
//        offlinePushInfo.setTitle(user.getName() + "发布动态时提到了你");
//        offlinePushInfo.setDesc(param.getRemark().length() > 50 ?
//                param.getRemark().substring(0, 50) + "..." :
//                param.getRemark());
//        pushInfo.setOfflinePushInfo(offlinePushInfo);
//        imUserService.pushBatch(pushInfo);

        return result;
    }

    @Override
    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {CoBusinessException.class, Exception.class})
    public void updatePinned(Long recommendId, Boolean pinned, Long buyerUserId) throws CoBusinessException {
        if (pinned) {
            //置顶操作先取消其他置顶（不需要锁）
            cereRecommendTrendsDAO.cancelAllPinned(buyerUserId);
        }
        //对具体动态的置顶/取消置顶操作加锁
        String key = CacheKeyConstants.RECOMMEND_PINNED_LOCK + recommendId;
        RLock redissonLock = redissonClient.getLock(key);
        redissonLock.lock(10, TimeUnit.SECONDS);
        try {
            String updateTime = TimeUtils.yyMMddHHmmss();
            int number = cereRecommendTrendsDAO.updatePinned(recommendId, pinned, updateTime, buyerUserId);
        } catch (Exception e) {
            throw new CoBusinessException(CoReturnFormat.FAIL, "操作失败: " + e.getMessage());
        } finally {
            redissonLock.unlock();
        }
    }

    @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {CoBusinessException.class, Exception.class})
    @Override
    public Integer deleteRecommend(Long recommendId, Long buyerUserId) {
        //删除动态
        Integer number = cereRecommendTrendsDAO.deleteById(recommendId);


        deleteRecommendRelations(recommendId);

        return number;

    }

    @Async
    public void deleteRecommendRelations(Long recommendId) {
        try {
            System.out.println("开始异步删除动态关联数据: recommendId=" + recommendId);

            // 并行删除关联数据
            CompletableFuture<Void> likesFuture = CompletableFuture.runAsync(() ->
                    cereRecommendLikesDAO.deleteByRecommendId(recommendId), sysThreadPool.getAsyncExecutor());

            CompletableFuture<Void> collectFuture = CompletableFuture.runAsync(() ->
                    cereBuyerCollectDAO.deleteByRecommendId(recommendId), sysThreadPool.getAsyncExecutor());

            CompletableFuture<Void> typeFuture = CompletableFuture.runAsync(() ->
                    cereRecommendTypeRelationDAO.deleteByRecommendId(recommendId), sysThreadPool.getAsyncExecutor());

            CompletableFuture<Void> commentFuture = CompletableFuture.runAsync(() ->
                    cereRecommendCommentService.removeByRecommendId(recommendId), sysThreadPool.getAsyncExecutor());

            // 等待所有删除操作完成
            CompletableFuture.allOf(likesFuture, collectFuture, typeFuture, commentFuture).join();

            System.out.println("异步删除动态关联数据完成: recommendId=" + recommendId);

        } catch (Exception e) {
            System.err.println("异步删除动态关联数据失败: recommendId=" + recommendId + ", error: " + e.getMessage());
            // 可以在这里添加失败处理逻辑
        }
    }


    @Override
    public Page<RecommendPageVO> getCollectAndLikePage(RecommendLikeDTO param, CereBuyerUser user) {
        if (param.getFilter() == 1) {
            //收藏
            Page<RecommendPageVO> page = cereBuyerCollectService.getCollectRecommendPage(user, param);
            if (ObjectUtil.isNotEmpty(page) && CollectionUtil.isNotEmpty(page.getList())) {
                fillUserInfo(page.getList(), user, true);
                return page;
            }
            return new Page<>(Collections.emptyList(), 0);
        } else {
            //赞过
            Page<RecommendPageVO> page = cereRecommendLikesService.getLikeRecommendPage(user.getBuyerUserId(), param);
            if (ObjectUtil.isNotEmpty(page) && CollectionUtil.isNotEmpty(page.getList())) {
                fillUserInfo(page.getList(), user, true);
                return page;
            }
            return new Page<>(Collections.emptyList(), 0);
        }
    }

    /**
     * 填充话题中的用户点赞和收藏状态
     *
     * @param pageList
     * @param user
     */
    private void fillUserInfo(List<RecommendPageVO> pageList, CereBuyerUser user, Boolean isSelf) {
        if (EmptyUtils.isEmpty(pageList) || user.getBuyerUserId() == null) {
            return;
        }

        //获取动态id列表
        List<Long> recommendIds = pageList.stream()
                .map(RecommendPageVO::getRecommendId)
                .collect(Collectors.toList());

        //批量查询当前用户关于动态的点赞和收藏状态
        Set<RecommendPageVO> collectAndLikeSet = cereRecommendTrendsDAO.getCollectAndLike(recommendIds, user.getBuyerUserId(), RecommendLikeTypeEnum.RECOMMEND.getCode());

        //批量查询当前用户关于动态的收藏数量
//        List<RecommendCollectVO> collectCounts = cereBuyerCollectDAO.getCollectByRecommendIds(recommendIds);

        //判断当前用户是否关注了动态发布者
        FollowUserResp resp = null;
        if (!isSelf) {
            FollowCheckReq req = new FollowCheckReq();
            req.setFrom_Account(String.valueOf(user.getBuyerUserId()));
            req.setTo_Account(pageList.stream().map(RecommendPageVO::getPublisherId).map(String::valueOf).toArray(String[]::new));
            resp = imUserService.followCheck(req);
        }
        //转换为map
        Map<Long, RecommendPageVO> collectAndLikeMap = collectAndLikeSet.stream()
                .collect(Collectors.toMap(RecommendPageVO::getRecommendId, Function.identity()));

        // 将收藏数量转换为map，方便后续查找
//        Map<Long, Integer> collectCountMap = collectCounts.stream()
//                .collect(Collectors.toMap(RecommendCollectVO::getRecommendId, RecommendCollectVO::getCollectCount));

        // 将关注状态转换为map，方便后续查找
        Map<String, Integer> concernStatusMap = new HashMap<>();
        if (!isSelf) {
            if (resp != null &&
                    "OK".equals(resp.getActionStatus()) &&
                    resp.getResultItem() != null) {

                concernStatusMap = resp.getResultItem().stream()
                        .filter(item -> item.getResultCode() == 0) // 只处理成功的请求
                        .collect(Collectors.toMap(
                                FollowUserResp.FollowAdd::getTo_Account,
                                FollowUserResp.FollowAdd::getFollowType,
                                (existing, replacement) -> existing)); // 处理重复key的情况
            }
        }

        // 设置个性化信息
        for (RecommendPageVO vo : pageList) {
            RecommendPageVO userStateVO = collectAndLikeMap.get(vo.getRecommendId());
            if (userStateVO != null) {
                vo.setLikeStatus(userStateVO.getLikeStatus());
                vo.setCollectStatus(userStateVO.getCollectStatus());
            } else {
                // 如果没有查到记录，设置默认值
                vo.setLikeStatus(0);
                vo.setCollectStatus(0);
            }

            // 设置收藏数量
//            vo.setCollectCount(collectCountMap.getOrDefault(vo.getRecommendId(), 0));
            Long collectCount = redisUtil.getLikeCount(RedisEnum.USER_COLLECT_KEY.getKey(), String.valueOf(vo.getRecommendId()));
            vo.setCollectCount(collectCount.intValue() + vo.getCollectCount());

            //设置点赞数量
            Long likeCount = redisUtil.getLikeCount(RedisEnum.USER_LIKE_KEY.getKey(), String.valueOf(vo.getRecommendId()));
            vo.setLikeCount(likeCount.intValue() + vo.getLikeCount());

            //设置评论数量
            Long commentCount = redisUtil.getLikeCount(RedisEnum.USER_COMMENT_KEY.getKey(), String.valueOf(vo.getRecommendId()));
            vo.setCommentCount(commentCount.intValue() + vo.getCommentCount());


            // 填充关注状态
            // 根据FollowType转换为前端需要的关注状态(0-未关注，1-已关注)
            if (!isSelf) {
                Integer followType = concernStatusMap.get(String.valueOf(vo.getPublisherId()));
                if (followType != null && (followType == 2 || followType == 3)) {
                    // 2-当前用户关注了发布者，3-互相关注，这两种情况都表示已关注
                    vo.setConcernStatus(1);
                } else {
                    // 0-没有关系，1-发布者关注了当前用户，其他情况都表示未关注
                    vo.setConcernStatus(0);
                }
            }
        }
    }

    /*
      首页动态列表
     */
    private Page<RecommendPageVO> getRecommendWithIndex(RecommendPageDTO param, CereBuyerUser user) {
      /*  List<Long> nearbyUserIds = null;
        if (ObjectUtil.isNotEmpty(param.getIsNearby()) && param.getIsNearby()) {
            List<GeoResult<RedisGeoCommands.GeoLocation<String>>> nearbyByUserList = nearbyService.findNearbyByUserId(user.getBuyerUserId(), 100.00, Metrics.KILOMETERS);
            //将nearbyByUserList转换为Long类型集合
            nearbyUserIds = nearbyByUserList.stream().map(GeoResult::getContent).map(RedisGeoCommands.GeoLocation::getName).map(Long::parseLong).collect(Collectors.toList());
            if (CollectionUtil.isEmpty(nearbyUserIds)) {
                return new Page<>(Collections.emptyList(), 0);
            }
        }*/
        String userGeoHash = null;
        if (ObjectUtil.isNotEmpty(param.getIsNearby()) && param.getIsNearby()) {
            userGeoHash = nearbyService.getUserGeoHash(user.getBuyerUserId(), 5);
        }
        //设置分页参数
        PageHelper.startPage(param.getPage(), param.getPageSize());
        List<RecommendPageVO> recommendPageVO = cereRecommendTrendsDAO.getTrendByIds(param, user.getBuyerUserId(), userGeoHash);
        if (CollectionUtil.isEmpty(recommendPageVO)) {
            return new Page<>(recommendPageVO, 0);
        }
        //查询用户行为信息
        fillUserInfo(recommendPageVO, user, false);
        recommendPageVO.forEach(RecommendPageVO::init);
        PageInfo<RecommendPageVO> pageInfo = new PageInfo<>(recommendPageVO);
        Page<RecommendPageVO> result = new Page<>(pageInfo.getList(), pageInfo.getTotal());
        return result;
    }

    /*
      话题详情页的动态列表
     */
    private Page<RecommendPageVO> getRecommendWithType(RecommendPageDTO param, CereBuyerUser user) throws CoBusinessException {
        if (param.getRecommendTypeId() != null) {
            if (param.getSort() == null) {
                param.setSort(1);
            }
            //redis没有数据则查询数据库
            PageHelper.startPage(param.getPage(), param.getPageSize());
            List<RecommendPageVO> pageList = cereRecommendTrendsDAO.getTrendByIds(param, null, null);
            pageList.forEach(RecommendPageVO::init);
            fillUserInfo(pageList, user, false);
            PageInfo<RecommendPageVO> pageInfo = new PageInfo<>(pageList);
            return new Page<>(pageList, pageInfo.getTotal());
        }
        throw new CoBusinessException(CoReturnFormat.PARAM_INVALID);
    }

    /*
      我的和他人的个人中心的动态列表
     */
    private Page<RecommendPageVO> getRecommendWithUser(RecommendPageDTO param, CereBuyerUser user) {
        //封装分页参数
        PageHelper.startPage(param.getPage(), param.getPageSize());
        List<RecommendPageVO> pageVOS = cereRecommendTrendsDAO.getTrendByIds(param, user.getBuyerUserId(), null);
        pageVOS.forEach(RecommendPageVO::init);
        fillUserInfo(pageVOS, user, false);
        PageInfo<RecommendPageVO> pageInfo = new PageInfo<>(pageVOS);
        Page<RecommendPageVO> page = new Page<>(pageInfo.getList(), pageInfo.getTotal());
        return page;
    }

    /**
     * 搜索页动态列表
     */
    private Page<RecommendPageVO> getRecommendWithSearch(RecommendPageDTO param, CereBuyerUser user) {
        //封装分页参数
        PageHelper.startPage(param.getPage(), param.getPageSize());
        List<RecommendPageVO> pageVOS = cereRecommendTrendsDAO.getTrendByIds(param, user.getBuyerUserId(), null);
        pageVOS.forEach(RecommendPageVO::init);
        fillUserInfo(pageVOS, user, false);
        PageInfo<RecommendPageVO> pageInfo = new PageInfo<>(pageVOS);
        Page<RecommendPageVO> page = new Page<>(pageInfo.getList(), pageInfo.getTotal());
        return page;
    }


    @Override
    public Page<RecommendPageVO> getMyConcernRecommends(RecommendPageDTO param, CereBuyerUser user) {
        //获取当前用户关注列表
        //第一次调用
        List<String> list = new ArrayList<>();
        FollowGetReq followGetReq = new FollowGetReq();
        followGetReq.setFrom_Account(String.valueOf(user.getBuyerUserId()));
        followGetReq.setFollowType(2);
        followGetReq.setWantNum(1000);
        FollowGetResp followList = imUserService.getFollowList(followGetReq);
        if (followList != null && "OK".equals(followList.getActionStatus()) && followList.getFollowItem() != null) {
            followList.getFollowItem().forEach(vo -> list.add(vo.getTo_Account()));
        }
        if (followList == null || !"OK".equals(followList.getActionStatus())) {
            log.warn("Failed to get follow list for user: {}, response: {}", user.getBuyerUserId(), followList);
        }
        //循环次数限制
        //循环次数限制
        int maxCount = 5;
        int count = 0;
        String nextCursor = followList != null ? followList.getNextCursor() : null;

        while (nextCursor != null && !nextCursor.isEmpty() && count < maxCount) {
            //如果还有游标，则继续调用
            FollowGetReq req = new FollowGetReq();
            followGetReq.setFrom_Account(String.valueOf(user.getBuyerUserId()));
            followGetReq.setFollowType(2);
            followGetReq.setWantNum(1000);
            followGetReq.setStartCursor(nextCursor);
            FollowGetResp newFollowList = imUserService.getFollowList(req);
            //添加到列表中
            newFollowList.getFollowItem().forEach(vo -> list.add(vo.getTo_Account()));
            nextCursor = newFollowList.getNextCursor();
            count++;
        }
        if (CollectionUtil.isEmpty(list)) {
            return new Page<>(Collections.emptyList(), 0);
        }
        List<Long> ids = new ArrayList<>(list.size());
        for (String str : list) {
            if (StrUtil.isNotBlank(str)) {
                ids.add(Long.parseLong(str.trim()));
            }
        }
        //配置分页插件
        PageHelper.startPage(param.getPage(), param.getPageSize());
        List<RecommendPageVO> pageVOS = cereRecommendTrendsDAO.getMyConcernRecommends(ids, user.getBuyerUserId(), param.getBlockedUserIds());
        for (RecommendPageVO pageVO : pageVOS) {
            pageVO.init();
        }
        fillUserInfo(pageVOS, user, false);
        PageInfo<RecommendPageVO> pageInfo = new PageInfo<>(pageVOS);
        Page<RecommendPageVO> recommendPageVOPage = new Page<>(pageVOS, pageInfo.getTotal());
        return recommendPageVOPage;
    }

    @Override
    public AllSearchVO getAllSearch(RecommendPageDTO param, CereBuyerUser user) {
        PageHelper.startPage(param.getPage(), param.getPageSize());
        List<RecommendPageVO> trendVOS = cereRecommendTrendsDAO.getTrendByIds(param, user.getBuyerUserId(), null);
        trendVOS.forEach(RecommendPageVO::init);
        fillUserInfo(trendVOS, user, false);
        PageHelper.startPage(param.getPage(), param.getPageSize());
        List<UserDetailVO> userDetailList = cereBuyerUserService.getUserDetailList(param, user).getList();
        AllSearchVO allSearchVO = new AllSearchVO();
        allSearchVO.setRecommendPageVOList(trendVOS);
        allSearchVO.setUserDetailVOList(userDetailList);

        return allSearchVO;
    }

    @Override
    @Async
    public void addFootPrint(Long recommendId, CereBuyerUser user) {
        RecommendPageVO recommendDetail = cereRecommendTrendsDAO.getRecommendDetail(recommendId, user.getBuyerUserId());
        RecommendFootPrintDTO recommendFootPrintDTO = new RecommendFootPrintDTO();
        recommendFootPrintDTO.setRecommendPageVO(recommendDetail);
        addRecommendFootPrint(recommendFootPrintDTO, user.getBuyerUserId());
    }
}
